package com.ghh.encrypto;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Base64;

public class JCEExample {

	public JCEExample() {
	}

	public void encrypt() throws Exception {
//		KeyGenerator kg = KeyGenerator.getInstance("DES");
//		Key key = kg.generateKey();
//
//		byte[] desKeyData = { (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
//				(byte) 0x07, (byte) 0x08 };
//
//		desKeyData = "qweqeAasdsadwQW123213ASdasdasd".getBytes();
//
//		DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
//		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
//		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

		// AlgorithmParameters algParams =
		// AlgorithmParameters.getInstance("PBEWithMD5AndDES");
		SecretKey secretKey = loadSecretKey();
		
		Cipher c1 = Cipher.getInstance("DES");
		c1.init(Cipher.ENCRYPT_MODE, secretKey);

		byte[] encrytedData = c1.doFinal("Password1234".getBytes());

		byte[] base64 = Base64.encodeBase64(encrytedData);
		String encryptedText = new String(base64);
		System.out.println(new String(base64));

		c1.init(Cipher.DECRYPT_MODE, secretKey);
		byte[] b64 = encryptedText.getBytes("UTF-8");
		byte[] encdata = Base64.decodeBase64(b64);
		byte[] plainBytes = c1.doFinal(encdata);

		System.out.println(new String(plainBytes, "UTF-8"));

		// System.out.println(new String(plainBytes, Charset.forName("UTF-8")));
	}

	public void testKeystore() throws Exception {
		KeyStore ks = KeyStore.getInstance("JCEKS");

		// get user password and file input stream
		char[] password = "123".toCharArray();

		java.io.FileInputStream fis = null;
		try {
//			fis = new java.io.FileInputStream("keyStoreName");
			ks.load(null, password);
		} finally {
			if (fis != null) {
				fis.close();
			}
		}

//		KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("privateKeyAlias", password);
//		PrivateKey myPrivateKey = pkEntry.getPrivateKey();

		byte[] desKeyData = "qweqeAasdsadwQW123213ASdasdasd".getBytes();

		DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey mySecretKey = keyFactory.generateSecret(desKeySpec);
		
		// save my secret key
//		javax.crypto.SecretKey mySecretKey;
		KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey);
		ks.setEntry("secretKeyAlias", skEntry, new KeyStore.PasswordProtection(password));

		// store away the keystore
		java.io.FileOutputStream fos = null;
		try {
			fos = new java.io.FileOutputStream("newKeyStoreName");
			ks.store(fos, password);
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
	}

	private final static String algorithm = "DES";
	private final static String keyStorePassword = "123";
	private final static String keyStoreType = "JCEKS";
	private final static String keyStoreName = "keystore";
	
	public SecretKey createSecretKey() throws Exception {
		KeyGenerator kg = KeyGenerator.getInstance(algorithm);
		Key key = kg.generateKey();
		
		DESKeySpec desKeySpec = new DESKeySpec(key.getEncoded());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		return secretKey;
	}
	
	public void createKeyStore(SecretKey sKey) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
		KeyStore ks = KeyStore.getInstance(keyStoreType);
		char[] password = keyStorePassword.toCharArray();
		ks.load(null, password);

		// save secret key
		KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(sKey);
		ks.setEntry("secretKeyAlias", skEntry, new KeyStore.PasswordProtection(password));

		// store away the keystore
		java.io.FileOutputStream fos = null;
		try {
			fos = new java.io.FileOutputStream(keyStoreName);
			ks.store(fos, password);
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
	}
	
	public SecretKey loadSecretKey() throws Exception {
		SecretKey sKey = null;
		
		KeyStore ks = KeyStore.getInstance(keyStoreType);
		char[] password = keyStorePassword.toCharArray();

		java.io.FileInputStream fis = null;
		try {
			fis = new java.io.FileInputStream(keyStoreName);
			ks.load(fis, password);
		} catch (FileNotFoundException e) {
			sKey = createSecretKey();
			createKeyStore(sKey);
			return sKey;
		} finally {
			if (fis != null) {
				fis.close();
			}
		}
		
		KeyStore.SecretKeyEntry pkEntry = (KeyStore.SecretKeyEntry) ks.getEntry("secretKeyAlias", new KeyStore.PasswordProtection(password));
		sKey = pkEntry.getSecretKey();
		return sKey;
	}
	
	public static void main(String[] args) throws Exception {
		JCEExample jce = new JCEExample();
		jce.encrypt();
//		SecretKey skey = jce.loadSecretKey();
//		skey.getEncoded()
	}
}
